﻿using Zbk_shop.Models;
using Zbk_shop.Models.Database;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Zbk_shop.Service
{
    /// <summary>
    /// 购物车服务类
    /// </summary>
    public class CarService : ICarService
    {
        //Redsi服务
        private readonly IDatabase _redis;
        private readonly Zbk_shopContext _db;
        public CarService(Zbk_shopContext db)
        {
            //获取redis的链接对象
            //_redis = redisHelper.GetDatabase();
            _db = db;
        }

        #region Redis实现购物车

        //加入购物车 用户把商品 加入购物车 记录购物车商品数量
        //用户 key  userCar+用户Id
        //商品         数量
        //键名         键值
        //商品Id        2
        //GoodId:3      3
        //GoodId:6      1

        /// <summary>
        /// 加入购物车
        /// </summary>
        public void AddCarForRedis(string userId, int goodId)
        {
            //在Hash数据里 找有没有键名数据（商品Id）
            //找到的话 键值+1
            //找不到   创建这个键值对 键名：商品Id   键值：1
            var key = "UserCar_" + userId;
            //将商品添加进购物车
            _redis.HashIncrement(key, goodId);
        }
        /// <summary>
        /// 减少购物车商品
        /// </summary>
        public void DiffCarForRedis(string userId, int goodId)
        {
            var key = "UserCar_" + userId;
            //把hash的键值数减1
            var value = _redis.HashDecrement(key, goodId);
            //当数量减少后 为0 删除掉这个键
            if (value <= 0)
            {
                //删除
                _redis.HashDelete(key, goodId);
            }
        }
        /// <summary>
        /// 删除购物车商品
        /// </summary>
        public void DeleteCarForRedis(string userId, int goodId)
        {
            var key = "UserCar_" + userId;
            //删除
            _redis.HashDelete(key, goodId);
        }

        //购物车商品列表（商品标题、商品图片、商品Id,购物车商品数量）
        /// <summary>
        /// 购物车商品列表
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<CarGoodModel> GetCarGoods(string userId)
        {
            var list = new List<CarGoodModel>();
            var key = "UserCar_" + userId;
            //获取购物车 所有hash数据
            var hashData = _redis.HashGetAll(key);
            // 商品Id  数量
            //  2      1 
            //  3      2
            foreach (var item in hashData)
            {
                // item.Name;  商品Id  主键
                // item.Value  数量
                var good = _db.Goods.FirstOrDefault(x => x.GoodId == (int)item.Name);
                if (good != null)
                {
                    list.Add(new CarGoodModel
                    {
                        Count = (int)item.Value,
                        GoodId = (int)item.Name,
                        Title = good.Title,
                        Photo = good.Photo,
                        Price = good.Price
                    });
                }

            }
            return list;
        }

        #endregion

        #region 数据库实现购物车

        /// <summary>
        /// 添加购物车
        /// </summary>
        public bool AddCardForSQL(int userId, int goodId)
        {
            //在数据库里 找有没有数据（商品Id）
            var car = _db.Cars.FirstOrDefault(x => x.UserId == userId && x.GoodId == goodId);

            //找到的话 
            if (car != null)
            {
                //数量+1
                car.Count++;
                //更新记录
                _db.Cars.Update(car);
            }
            //找不到    
            else
            {
                //创建这个记录
                _db.Cars.Add(new Car
                {
                    UserId = userId,
                    GoodId = goodId,
                    Count = 1,
                    CreateTime = DateTime.Now
                });
            }
            return _db.SaveChanges() > 0;
        }
        /// <summary>
        /// 减少购物车商品
        /// </summary>
        /// <returns></returns>
        public bool DiffCarForSQL(int userId, int goodId)
        {
            //查询有没有这个商品 有的话减少
            var car = _db.Cars.FirstOrDefault(x => x.UserId == userId && x.GoodId == goodId);
            if (car != null)
            {
                car.Count--;
                //如果数量==0 删除记录
                if (car.Count <= 0)
                {
                    _db.Cars.Remove(car);
                }
                else
                {
                    _db.Cars.Update(car);
                }
                return _db.SaveChanges() > 0;
            }
            //没得话 没得减
            return false;
        }
        /// <summary>
        /// 删除购物车商品
        /// </summary>
        /// <returns></returns>
        public bool DeleteCarForSQL(int userId, int goodId)
        {
            var car = _db.Cars.FirstOrDefault(x => x.UserId == userId && x.GoodId == goodId);
            if (car != null)
            {
                _db.Cars.Remove(car);
                return _db.SaveChanges() > 0;
            }
            //没得话 没得减
            return false;
        }

        /// <summary>
        /// 清空购物车商品
        /// </summary>
        /// <returns></returns>
        public void RemoveCarForSQL(int userId)
        {
            var cars = _db.Cars.Where(x => x.UserId == userId);
            foreach(var item in cars)
            {
                _db.Cars.Remove(item);
            }
            _db.SaveChanges();
        }

        //购物车商品列表（商品标题、商品图片、商品Id,购物车商品数量）
        /// <summary>
        /// 购物车商品列表
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<CarGoodModel> GetCarGoodsForSQL(int userId)
        {
            //商品Id 和 数量
            var list = _db.Cars
                 .Where(X => X.UserId == userId)
                 //商品标题、商品图片、商品价格
                 //关联查询 商品Id 商品表关联
                 //4个参数 1关联的表 2、第一个表关联字段 商品Id 3、第二表的关联字段 4构造新的对象
                 .Join(_db.Goods, x => x.GoodId, y => y.GoodId, (x, y) => new CarGoodModel
                 {
                     GoodId = x.GoodId,
                     Count = x.Count,
                     Title = y.Title,
                     Photo = y.Photo,
                     Price = y.Price
                 })
                 .ToList(); ;

            return list;
        }

        #endregion
    }
}
